﻿using System;
using System.Diagnostics;
using System.Threading;

namespace HslCommunication.Core
{
	/// <summary>
	/// 一个用于多线程并发处理数据的模型类，适用于处理数据量非常庞大的情况
	/// </summary>
	/// <typeparam name="T">等待处理的数据类型</typeparam>
	// Token: 0x0200011F RID: 287
	public sealed class SoftMultiTask<T>
	{
		/// <summary>
		/// 实例化一个数据处理对象
		/// </summary>
		/// <param name="dataList">数据处理列表</param>
		/// <param name="operater">数据操作方法，应该是相对耗时的任务</param>
		/// <param name="threadCount">需要使用的线程数</param>
		// Token: 0x060018A8 RID: 6312 RVA: 0x0007D6E4 File Offset: 0x0007B8E4
		public SoftMultiTask(T[] dataList, Func<T, bool> operater, int threadCount = 10)
		{
			if (dataList == null)
			{
				throw new ArgumentNullException("dataList");
			}
			this.m_dataList = dataList;
			if (operater == null)
			{
				throw new ArgumentNullException("operater");
			}
			this.m_operater = operater;
			bool flag = threadCount < 1;
			if (flag)
			{
				throw new ArgumentException("threadCount can not less than 1", "threadCount");
			}
			this.m_threadCount = threadCount;
			Interlocked.Add(ref this.m_opCount, dataList.Length);
			Interlocked.Add(ref this.m_opThreadCount, threadCount);
		}

		/// <summary>
		/// 异常发生时事件
		/// </summary>
		// Token: 0x14000037 RID: 55
		// (add) Token: 0x060018A9 RID: 6313 RVA: 0x0007D7C0 File Offset: 0x0007B9C0
		// (remove) Token: 0x060018AA RID: 6314 RVA: 0x0007D7F8 File Offset: 0x0007B9F8
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		public event SoftMultiTask<T>.MultiInfo OnExceptionOccur;

		/// <summary>
		/// 报告处理进度时发生
		/// </summary>
		// Token: 0x14000038 RID: 56
		// (add) Token: 0x060018AB RID: 6315 RVA: 0x0007D830 File Offset: 0x0007BA30
		// (remove) Token: 0x060018AC RID: 6316 RVA: 0x0007D868 File Offset: 0x0007BA68
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		public event SoftMultiTask<T>.MultiInfoTwo OnReportProgress;

		/// <summary>
		/// 启动多线程进行数据处理
		/// </summary>
		// Token: 0x060018AD RID: 6317 RVA: 0x0007D8A0 File Offset: 0x0007BAA0
		public void StartOperater()
		{
			bool flag = Interlocked.CompareExchange(ref this.m_runStatus, 0, 1) == 0;
			if (flag)
			{
				for (int i = 0; i < this.m_threadCount; i++)
				{
					new Thread(new ThreadStart(this.ThreadBackground))
					{
						IsBackground = true
					}.Start();
				}
				this.JustEnded();
			}
		}

		/// <summary>
		/// 暂停当前的操作
		/// </summary>
		// Token: 0x060018AE RID: 6318 RVA: 0x0007D904 File Offset: 0x0007BB04
		public void StopOperater()
		{
			bool flag = this.m_runStatus == 1;
			if (flag)
			{
				this.m_isRunningStop = true;
			}
		}

		/// <summary>
		/// 恢复暂停的操作
		/// </summary>
		// Token: 0x060018AF RID: 6319 RVA: 0x0007D928 File Offset: 0x0007BB28
		public void ResumeOperater()
		{
			this.m_isRunningStop = false;
		}

		/// <summary>
		/// 直接手动强制结束操作
		/// </summary>
		// Token: 0x060018B0 RID: 6320 RVA: 0x0007D934 File Offset: 0x0007BB34
		public void EndedOperater()
		{
			bool flag = this.m_runStatus == 1;
			if (flag)
			{
				this.m_isQuit = true;
			}
		}

		/// <summary>
		/// 在发生错误的时候是否强制退出后续的操作
		/// </summary>
		// Token: 0x17000537 RID: 1335
		// (get) Token: 0x060018B1 RID: 6321 RVA: 0x0007D958 File Offset: 0x0007BB58
		// (set) Token: 0x060018B2 RID: 6322 RVA: 0x0007D970 File Offset: 0x0007BB70
		public bool IsQuitAfterException
		{
			get
			{
				return this.m_isQuitAfterException;
			}
			set
			{
				this.m_isQuitAfterException = value;
			}
		}

		// Token: 0x060018B3 RID: 6323 RVA: 0x0007D97C File Offset: 0x0007BB7C
		private void ThreadBackground()
		{
			for (;;)
			{
				while (this.m_isRunningStop)
				{
				}
				int num = Interlocked.Decrement(ref this.m_opCount);
				bool flag = num < 0;
				if (flag)
				{
					break;
				}
				T t = this.m_dataList[num];
				bool flag2 = false;
				bool flag3 = false;
				try
				{
					bool flag4 = !this.m_isQuit;
					if (flag4)
					{
						flag2 = this.m_operater(t);
					}
				}
				catch (Exception ex)
				{
					flag3 = true;
					SoftMultiTask<T>.MultiInfo onExceptionOccur = this.OnExceptionOccur;
					if (onExceptionOccur != null)
					{
						onExceptionOccur(t, ex);
					}
					bool isQuitAfterException = this.m_isQuitAfterException;
					if (isQuitAfterException)
					{
						this.EndedOperater();
					}
				}
				finally
				{
					this.HybirdLock.Enter();
					bool flag5 = flag2;
					if (flag5)
					{
						this.m_successCount++;
					}
					bool flag6 = flag3;
					if (flag6)
					{
						this.m_failedCount++;
					}
					this.m_finishCount++;
					SoftMultiTask<T>.MultiInfoTwo onReportProgress = this.OnReportProgress;
					if (onReportProgress != null)
					{
						onReportProgress(this.m_finishCount, this.m_dataList.Length, this.m_successCount, this.m_failedCount);
					}
					this.HybirdLock.Leave();
				}
			}
			this.JustEnded();
		}

		// Token: 0x060018B4 RID: 6324 RVA: 0x0007DAD4 File Offset: 0x0007BCD4
		private void JustEnded()
		{
			bool flag = Interlocked.Decrement(ref this.m_opThreadCount) == 0;
			if (flag)
			{
				this.m_finishCount = 0;
				this.m_failedCount = 0;
				this.m_successCount = 0;
				Interlocked.Exchange(ref this.m_opCount, this.m_dataList.Length);
				Interlocked.Exchange(ref this.m_opThreadCount, this.m_threadCount + 1);
				Interlocked.Exchange(ref this.m_runStatus, 0);
				this.m_isRunningStop = false;
				this.m_isQuit = false;
			}
		}

		/// <summary>
		/// 操作总数，判定操作是否完成
		/// </summary>
		// Token: 0x04000580 RID: 1408
		private int m_opCount = 0;

		/// <summary>
		/// 判断是否所有的线程是否处理完成
		/// </summary>
		// Token: 0x04000581 RID: 1409
		private int m_opThreadCount = 1;

		/// <summary>
		/// 准备启动的处理数据的线程数量
		/// </summary>
		// Token: 0x04000582 RID: 1410
		private int m_threadCount = 10;

		/// <summary>
		/// 指示多线程处理是否在运行中，防止冗余调用
		/// </summary>
		// Token: 0x04000583 RID: 1411
		private int m_runStatus = 0;

		/// <summary>
		/// 列表数据
		/// </summary>
		// Token: 0x04000584 RID: 1412
		private T[] m_dataList = null;

		/// <summary>
		/// 需要操作的方法
		/// </summary>
		// Token: 0x04000585 RID: 1413
		private Func<T, bool> m_operater = null;

		/// <summary>
		/// 已处理完成数量，无论是否异常
		/// </summary>
		// Token: 0x04000588 RID: 1416
		private int m_finishCount = 0;

		/// <summary>
		/// 处理完成并实现操作数量
		/// </summary>
		// Token: 0x04000589 RID: 1417
		private int m_successCount = 0;

		/// <summary>
		/// 处理过程中异常数量
		/// </summary>
		// Token: 0x0400058A RID: 1418
		private int m_failedCount = 0;

		/// <summary>
		/// 用于触发事件的混合线程锁
		/// </summary>
		// Token: 0x0400058B RID: 1419
		private SimpleHybirdLock HybirdLock = new SimpleHybirdLock();

		/// <summary>
		/// 指示处理状态是否为暂停状态
		/// </summary>
		// Token: 0x0400058C RID: 1420
		private bool m_isRunningStop = false;

		/// <summary>
		/// 指示系统是否需要强制退出
		/// </summary>
		// Token: 0x0400058D RID: 1421
		private bool m_isQuit = false;

		/// <summary>
		/// 在发生错误的时候是否强制退出后续的操作
		/// </summary>
		// Token: 0x0400058E RID: 1422
		private bool m_isQuitAfterException = false;

		/// <summary>
		/// 一个双参数委托
		/// </summary>
		/// <param name="item"></param>
		/// <param name="ex"></param>
		// Token: 0x02000747 RID: 1863
		// (Invoke) Token: 0x0600317A RID: 12666
		public delegate void MultiInfo(T item, Exception ex);

		/// <summary>
		/// 用于报告进度的委托，当finish等于count时，任务完成
		/// </summary>
		/// <param name="finish">已完成操作数量</param>
		/// <param name="count">总数量</param>
		/// <param name="success">成功数量</param>
		/// <param name="failed">失败数量</param>
		// Token: 0x02000748 RID: 1864
		// (Invoke) Token: 0x0600317E RID: 12670
		public delegate void MultiInfoTwo(int finish, int count, int success, int failed);
	}
}
